package com.zxb.base.auth;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zxb.base.auth.service.AuthOrgService;
import com.zxb.base.auth.vo.DropOrgVo;
import com.zxb.core.common.A;
import com.zxb.core.common.C;
import com.zxb.core.common.R;
import com.zxb.core.dao.auth.AuthOrg;
import com.zxb.core.dao.auth.AuthOrgDao;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author Zxb
 */
@RestController
@RequiredArgsConstructor
public class OrgController {

    private final AuthOrgDao orgDao;
    private final AuthOrgService orgService;

    @PostMapping("/org/root")
    @Transactional(rollbackFor = Exception.class)
    public R<?> initRoot() {
        String name = "组织架构";
        AuthOrg root = orgDao.getOne(new LambdaQueryWrapper<AuthOrg>()
                .isNull(AuthOrg::getPid));
        if (root != null) {
            return R.success(root);
        }
        root = new AuthOrg();
        root.setPid(null);
        root.setName(name);
        root.setLayer(1);
        root.setSort(1);
        orgDao.save(root);
        orgService.generateLink(root);
        return R.success(root);
    }

    @GetMapping("/org/next")
    public R<?> next(Long pid) {
        List<AuthOrg> list = orgDao.list(new LambdaQueryWrapper<AuthOrg>()
                .eq(AuthOrg::getPid, pid)
                .orderByAsc(AuthOrg::getSort));
        return R.success(list);
    }

    @PostMapping("/org/add")
    @Transactional(rollbackFor = Exception.class)
    public R<?> add(@RequestBody Long pid) {
        AuthOrg parent = orgDao.getById(pid);
        A.isInDatabase(parent, "上级组织");

        AuthOrg org = new AuthOrg();
        org.setPid(pid);
        org.setName(orgService.generateNewName(pid));
        org.setLayer(parent.getLayer() + 1);

        Integer sort = orgService.findMaxSort(pid);
        org.setSort(sort + 1);
        orgDao.save(org);
        orgService.generateLink(org);
        return R.success(org);
    }

    @PostMapping("/org/del")
    public R<?> del(@RequestBody Long id) {
        orgDao.removeById(id);
        return R.success();
    }

    @GetMapping("/org/info")
    public R<?> info(Long id) {
        AuthOrg org = orgDao.getById(id);
        return R.success(org);
    }

    @PostMapping("/org/update")
    @Transactional(rollbackFor = Exception.class)
    public R<?> update(@RequestBody AuthOrg org) {
        AuthOrg old = orgDao.getById(org.getId());
        A.isInDatabase(old, "当前组织");
        if (orgService.isNameConflict(org.getId(), org.getName())) {
            return R.error("组织名称冲突");
        }
        if (StrUtil.isNotBlank(org.getCode())
                && orgService.isCodeConflict(org.getId(), org.getCode())) {
            return R.error("组织编码冲突");
        }
        BeanUtil.copyProperties(org, old, C.IGNORED_PROPERTIES);
        orgDao.updateById(old);
        orgService.generateLink(old);
        return R.success(old);
    }

    @PostMapping("/org/drop")
    @Transactional(rollbackFor = Exception.class)
    public R<?> drop(@RequestBody DropOrgVo param) {
        Long dragId = param.getDragId();
        Long dropId = param.getDropId();
        Integer position = param.getPosition();

        AuthOrg dragObj = orgDao.getById(dragId);
        AuthOrg dropObj = orgDao.getById(dropId);
        if (position == 0) {
            orgService.moveInner(dragObj, dropObj);
        } else if (position > 0) {
            orgService.moveAfter(dragObj, dropObj);
        } else {
            orgService.moveBefore(dragObj, dropObj);
        }
        orgService.generateLink(dragObj);
        return R.success();
    }

    @PostMapping("/org/sort")
    public R<?> sort(@RequestBody List<String> sortList) {
        sortList.stream().forEach(t -> {
            String[] arr = t.split("_");
            Long id = Long.parseLong(arr[0]);
            Integer sort = Integer.parseInt(arr[1]);
            AuthOrg org = orgDao.getById(id);
            org.setSort(sort);
            orgDao.updateById(org);
        });
        return R.success();
    }
}